#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iterator>
#include <vector>
#include <map>
#include "../include/ParametersParser.h"



ParametersParser::ParametersParser(int _argc, char** _argv) {
    this->m_argc = _argc;
    this->m_argv = _argv;
    if (this->m_argc <2) {
        std::cout << "krm-grep [-v] pattern [File(i)]\r\n" << std::endl;
        exit(-1);
    }

/*    for (unsigned i=0; i<sizeof(_argv)/sizeof(char); ++i)
        std::cout << "argv[" << i << "]: " << _argv[i] << std::endl;
    std::cout << "-v: " << this->containFlag("-v") << std::endl; */
    this->parseFlags();
    this->parseFiles();
    this->parsePattern();
  /*  for (unsigned i=0; i<this->m_files.size(); ++i) {
        std::cout << "file[" << i << "]: " << this->m_files[i] << "\r\n";
    }
    std::cout << std::endl;
    std::cout << "Params: \r\n";
    std::map<const char*, bool>::const_iterator it;
    for (it = m_parameters.begin(); it!=m_parameters.end(); ++it)
        std::cout << it->first << "\r\n";
*/
}

ParametersParser::~ParametersParser()
{
    //dtor
}

/**
 *
 * @brief Spradza,czy podano jakiś parametr i wrzuca wynik do mapy m_parameters
 */
bool ParametersParser::containFlag(const char* _flag) {
    int k = 0;
    if (this->m_argc>1) {
        while (k++ < this->m_argc-1) {
            if ((strcmp(this->m_argv[k], _flag) == 0)) {
                this->m_parameters.insert(std::pair<const char*, bool>("v", true));
                return true;
            }
        }
    }
    return false;
}

/**
 *
 * @brief Odnajduje przełącznik -f i czyta kolejne wyrazy zakładając, że są to nazwy plików
          Nie jest idiotoodporne.
 *
 */
void ParametersParser::parseFiles() {
    int k = 0;
    if (this->m_argc > 1) {
        while (k++ < this->m_argc-1)
            if ((strcmp(this->m_argv[k], "-f") == 0)) break;    // kolejny(e) parametry to nazwy plików
        while (k < this->m_argc-1) {
            m_files.push_back(m_argv[k+1]);
            ++k;
        }
    }
}

/**
 * @brief Znajduje wzorzec w parametrach programu. Wywolanie ma byc w postaci grep [-v] wzorzec [params] -f  [Plik(i)]
 *
 */
void ParametersParser::parsePattern() {
    if (this->m_argc > 1) {
        if ((strcmp(this->m_argv[1], "-v") == 0))
            this->m_pattern = this->m_argv[2];
        else
            this->m_pattern = this->m_argv[1];
    }
}

void ParametersParser::parseFlags() {
    // flagi -- fajniej by było jakby te flagi były gdzieś globalniej umieszczone, ale jest 02:01 am i nie chce działać ;)
    const char* flags[] = {"-l", "-c", "-i"};
    int k = 0;

    if (this->m_argc > 1) {
        while (k < this->m_argc-1) {
            for (unsigned i = 0; i < (sizeof(flags)/sizeof(flags[0])); ++i) {
                if (strcmp(this->m_argv[k], flags[i]) == 0)
                    m_parameters.insert(std::pair<const char*, bool>(flags[i], true));
            }
            ++k;
        }
    }
}

/** testowo, raczej nie do użytku */
const char* ParametersParser::getCommandOption(const char* name, const char*  ddefault) {
    const char  *res = 0;
    int         k = 0;
    if (this->m_argc > 0) {
        while (k < this->m_argc && strcmp(this->m_argv[k], name)) ++k;
        int k = 0;
        res = (k++ == this->m_argc ? ddefault : (k == this->m_argc ? this->m_argv[--k] : this->m_argv[k]));
    } else res = ddefault;
  return res;
}

std::vector<const char*> ParametersParser::getFilesList() const {
    return m_files;
}

std::map<const char*, bool> ParametersParser::getParametersList() const {
    return m_parameters;
}

std::string ParametersParser::getPattern() const {
    return m_pattern;
}
